fix: refresh stale squad.agent.md greeting version on re-init - #1995
Draft
tamirdresher wants to merge 1 commit into
Draft
fix: refresh stale squad.agent.md greeting version on re-init#1995tamirdresher wants to merge 1 commit into
tamirdresher wants to merge 1 commit into
Conversation
Re-running squad init against an already-initialized project could leave
the squad.agent.md first-response greeting (backtick-quoted ` Squad
v... `) stamped with an old version even though the HTML comment marker
and Identity Version: line were correctly refreshed.
Root cause: stampVersion (squad-cli) and stampVersionInContent
(squad-sdk) each replace three version locations, but the third regex only
matched the unresolved ` Squad v{version} ` placeholder. Once a real
version had been stamped once, the placeholder was gone, so later
re-stamps could no longer touch the greeting literal.
Fix: broaden the greeting regex in both functions to also match an
already-resolved ` Squad vX.Y.Z ` literal, so all three locations stay
idempotently in sync on every re-init or upgrade.
Adds regression coverage in test/cli/init.test.ts: a direct stampVersion
unit test, and a full re-init integration test that seeds a stale resolved
version in all three locations and asserts init.ts's existing-file
re-stamp brings them back in sync.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b73147c1-252d-473c-be2b-df22d9faf163
Contributor
🟡 Impact Analysis — PR #1995Risk tier: 🟡 MEDIUM 📊 Summary
🎯 Risk Factors
📦 Modules Affectedroot (1 file)
squad-cli (1 file)
squad-sdk (1 file)
tests (1 file)
This report is generated automatically for every PR. See #733 for details. |
Contributor
🛫 PR Readiness Check
PR Scope: 📦🔧 Mixed (product + infrastructure)
|
| Status | Check | Details |
|---|---|---|
| ✅ | Single commit | 1 commit — clean history |
| ❌ | Not in draft | PR is still in draft — mark as ready for review when done |
| ✅ | Branch up to date | Up to date with dev |
| ❌ | Copilot review | No Copilot review yet — it may still be processing |
| ✅ | Changeset present | Changeset file found |
| ✅ | Scope clean | No .squad/ or docs/proposals/ files |
| ✅ | No merge conflicts | No merge conflicts |
| ✅ | Copilot threads resolved | No Copilot review threads |
| ❌ | CI passing | 10 check(s) still running |
Files Changed (4 files, +74 −6)
| File | +/− |
|---|---|
.changeset/fix-reinit-stale-version-greeting.md |
+6 −0 |
packages/squad-cli/src/cli/core/version.ts |
+4 −2 |
packages/squad-sdk/src/config/init.ts |
+4 −2 |
test/cli/init.test.ts |
+60 −2 |
Total: +74 −6
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
Contributor
🏗️ Architectural Review
Automated architectural review — informational only. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Fixes
squad.agent.md's first-response greeting literal (backtick-quoted`Squad v...`) staying stamped with a stale version whensquad initis re-run against an already-initialized project, even though the HTML comment marker (<!-- version: ... -->) and the Identity- **Version:**line are correctly refreshed on the same re-run.Why
squad initalways callsstampVersion()on an existingsquad.agent.mdaftersdkInitSquad()returns, regardless ofskipExisting, to "ensure the version is fully stamped".stampVersion(inpackages/squad-cli/src/cli/core/version.ts) and its SDK counterpartstampVersionInContent(inpackages/squad-sdk/src/config/init.ts, used when generating a freshsquad.agent.mdfrom the template) each replace three version locations. The first two regexes (<!-- version: ... -->and- **Version:** ...) are written permissively and are idempotent — they match any prior value, resolved or not. The third regex, however, only matched the unresolved`Squad v{version}`placeholder token. Once a real version had been stamped once, the placeholder text no longer existed in the file, so every subsequent re-stamp silently left the greeting literal on whatever version it was last set to.Not affected:
squad upgradefully rewritessquad.agent.mdfrom the template (which always contains the unresolved placeholder) before stamping, so the placeholder is always present there — the regression is specific to the re-init /skipExisting=truepath.How
Widened the third regex in both
stampVersionandstampVersionInContentfrom matching only`Squad v\{version\}`to matching`Squad v[^`]*`— i.e. anything between`Squad vand the closing backtick. This still matches the unresolved placeholder, and now also matches an already-resolved semver (with or without a prerelease suffix), making the replacement idempotent regardless of the file's current state. Both implementations were kept in sync per existing convention (each package has its own copy of the stamping logic).Added regression coverage in
test/cli/init.test.ts:`Squad v0.9.0`literal (plus stale marker/Version line) and assertsstampVersion()refreshes all three locations.runInit()once, mutate the resultingsquad.agent.mdto simulate an older installed version in all three locations (not the{version}placeholder),runInit()again against the same project (hits theskipExisting=true/ existing-file path), and assert every version location — including the greeting literal — now matches the current version.PR Readiness Checklist
Branch & Commit
dev(upstream/dev, notmain)devBuild & Test
npm run build -w packages/squad-clipassesnpm run build -w packages/squad-sdk— fails onupstream/devbaseline, unrelated to this change (see Waivers)npx vitest run test/cli/init.test.ts(18/18, including 2 new regression tests)test/cli/upgrade.test.ts,test/cli/init-upgrade-parity.test.ts,test/init-sdk.test.ts,test/init.test.ts,test/init-scaffolding.test.ts(all pass in isolation; see Waivers for a flaky test under full-suite parallel load)npm test(full suite) — not run to completion; see Waiversnpm run lint— fails onupstream/devbaseline, unrelated to this change (see Waivers)npm run lint:eslinton changed files — 0 errors (63 pre-existingn/no-syncwarnings ininit.ts, untouched by this diff)Changeset
.changeset/fix-reinit-stale-version-greeting.md(patch, both@bradygaster/squad-cliand@bradygaster/squad-sdk)Docs
Exports
Breaking Changes
None.
Waivers
npm run build(squad-sdk) /npm run lint— both fail identically on a cleanupstream/devcheckout (verified by stashing this PR's changes and re-running) with 6 pre-existing TypeScript errors inpackages/squad-sdk/src/adapter/client.ts(RuntimeConnectionnot exported by@github/copilot-sdk,CopilotClientOptions.connection,ModelBilling.tokenPrices,CopilotClient.onLifecycle, etc.). This file is untouched by this PR. Requesting a maintainer confirm this is known baseline debt (skip-changelog/reviewer waiver as appropriate — not requestingskip-changelogsince a changeset is included).npm testrun — running the complete suite locally (npx vitest run, ~6400 tests, no path filter) produced widespread, unrelated failures across dozens of test files with no relation to this diff (e.g.test/storage-provider.test.ts,test/session-adapter.test.ts,test/scripts/check-shebang-eol.test.ts), consistent with local resource contention under full parallelism rather than a real regression. Also observed: at least one test in this run (apparently a self-upgrade/dogfooding test) wrote to this checkout's own.squad/config.jsonand.github/agents/squad.agent.md; both were reverted before committing and are not part of this PR's diff. Given the risk of further side effects against this real checkout, I did not force a full run to completion. All targeted and directly-adjacent suites (see above) pass. Requesting CI be the source of truth for the full-suite gate on this PR.test/init-scaffolding.test.tsintermittent failure under combined load —no-remote resilience (#579) > initSquad/runInit succeeds in a git repo with no remoteand adoctorsub-test flip between pass/fail depending on what else is running concurrently; the full file passes 26/26 in isolation on two separate runs. Not caused by this change (no code in this diff is exercised by that test).Do not link/close #1589 — related area but a different bug.